package net.xinshi.service.business.impl;

import com.alibaba.fastjson.JSON;
import net.xinshi.boot.AppConfig;
import net.xinshi.dal.automapper.model.Api;
import net.xinshi.exception.ApiException;
import net.xinshi.model.*;
import net.xinshi.service.atom.IAtomApiService;
import net.xinshi.service.business.IApiService;
import net.xinshi.utils.BeanUtils;
import net.xinshi.utils.ErrorCode;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author <a href="mailto:liukuo@xinshi.net">liukuo</a>
 * @version 1.0
 * @description
 * @since 2017/6/27.
 */
@Service("ApiService")
public class ApiServiceImpl implements IApiService {
    private static final Logger LOGGER = LogManager.getLogger(ApiServiceImpl.class);
    private static Map<String, ApiOutputDTO> API_MAP = new HashMap<String, ApiOutputDTO>();
    private static long LAST_LOAD_TIME = 0;

    @Autowired
    private IAtomApiService atomApiService;

    @Autowired
    private AppConfig appConfig;

    @Override
    public ApiOutputDTO queryApi(BaseIdInputDTO input) {
        LOGGER.info("查询API，根据id查询入参对象为 {}", JSON.toJSONString(input));
        try {
            if (input == null || input.getId() == null) {
                throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, "查询API功能查询入参对象为空");
            }
            Api data = atomApiService.selectByKey(input.getId());
            LOGGER.info("查询API功能，根据id查询结果为：" + JSON.toJSONString(data));
            ApiOutputDTO output = null;
            if (data != null) {
                output = BeanUtils.beanCopy(data, ApiOutputDTO.class);
            } else {
                throw new ApiException(ErrorCode.ERR_DATA_EMPTY_ERROR, ErrorCode.ERR_DATA_EMPTY_ERROR.getMsg());
            }
            return output;
        } catch (Exception e) {
            LOGGER.error("查询API，根据id查询失败，{}", e);
            if (e instanceof ApiException) {
                throw (ApiException) e;
            }
            e.printStackTrace();
            throw new ApiException(ErrorCode.ERR_DATA_OPER_ERROR);
        }
    }

    @Override
    public Map<String, ApiOutputDTO> getApiMap() {
        try {
            long now = System.currentTimeMillis();
            if (now - LAST_LOAD_TIME > appConfig.getRefreshInterval() * 60 * 1000) {
                List<Api> list = atomApiService.selectAll();
                API_MAP.clear();
                for (Api api : list) {
                    API_MAP.put(api.getApiId(), BeanUtils.beanCopy(api, ApiOutputDTO.class));
                }
                LAST_LOAD_TIME = now;
                LOGGER.info("查询API列表，查询间隔超过5分钟，重新查询,查询结果是：" + JSON.toJSONString(API_MAP));
            } else {
                LOGGER.info("查询API列表，查询间隔未超过5分钟，返回上次查询结果");
            }
            return API_MAP;
        } catch (Exception e) {
            LOGGER.error("查询API，根据id查询失败，{}", e);
            if (e instanceof ApiException) {
                throw (ApiException) e;
            }
            e.printStackTrace();
            throw new ApiException(ErrorCode.ERR_DATA_OPER_ERROR);
        }
    }

    @Override
    public void refreshApi() {
        try {
            List<Api> list = atomApiService.selectAll();
            API_MAP.clear();
            for (Api api : list) {
                API_MAP.put(api.getApiId(), BeanUtils.beanCopy(api, ApiOutputDTO.class));
            }
            LAST_LOAD_TIME = System.currentTimeMillis();
            LOGGER.info("刷新API列表，查询结果是：" + JSON.toJSONString(API_MAP));
        } catch (Exception e) {
            LOGGER.error("刷新API列表,异常，{}", e);
            e.printStackTrace();
            throw new ApiException(ErrorCode.ERR_DATA_OPER_ERROR);
        }
    }

    @Override
    public BasePageOutputDTO<ApiOutputDTO> queryApiList(ApiPageInputDTO input) {
        LOGGER.info("查询API列表，分页查询入参对象为 {}", JSON.toJSONString(input));
        try {
            if (input == null) {
                throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, "查询API列表，分页查询入参对象为空");
            }
            Map<String, Object> map = new HashMap<>();
            map.put("apiId", input.getApiId());
            map.put("apiName", input.getApiName());
            map.put("apiUrl", input.getApiUrl());
            if (StringUtils.isNotBlank(input.getBeginCreateTime())) {
                map.put("beginCreateTime", input.getBeginCreateTime());
            }
            if (StringUtils.isNotBlank(input.getEndCreateTime())) {
                map.put("endCreateTime", input.getEndCreateTime());
            }
            //{start},${pageSize}
            map.put("start", input.getStart());
            map.put("pageSize", input.getPageSize());

            long beginTime = System.currentTimeMillis();
            List<Api> dataList = atomApiService.searchApiByCriteria(map);
            int count = atomApiService.searchApiCount(map);
            long endTime = System.currentTimeMillis();

            LOGGER.info("查询API列表，查询耗时:{},分页查询结果为：{}", (endTime - beginTime), JSON.toJSONString(dataList));
            BasePageOutputDTO<ApiOutputDTO> outputs = new BasePageOutputDTO<ApiOutputDTO>();
            outputs.setPageSize(input.getPageSize());
            outputs.setCurrentPage(input.getStart());
            if (dataList != null) {
                for (Api r : dataList) {
                    ApiOutputDTO output = BeanUtils.beanCopy(r, ApiOutputDTO.class);
                    outputs.addList(output);
                }
                outputs.setTotalSize(count);
            }
            return outputs;
        } catch (Exception e) {
            LOGGER.error("查询API列表，分页查询失败，{}", e);
            if (e instanceof ApiException) {
                throw (ApiException) e;
            }
            throw new ApiException(ErrorCode.ERR_DATA_OPER_ERROR);
        }
    }

    @Override
    public Integer saveApi(ApiInputDTO input) {
        LOGGER.info("添加API，入参对象为 {}", JSON.toJSONString(input));
        try {
            if (input == null) {
                throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, "添加API，入参对象为空");
            }

            Api api = BeanUtils.beanCopy(input, Api.class);
            return atomApiService.save(api);
        } catch (Exception e) {
            LOGGER.error("添加API，保存失败，{}", e);
            if (e instanceof ApiException) {
                throw (ApiException) e;
            }
            throw new ApiException(ErrorCode.ERR_DATA_OPER_ERROR);
        }
    }

    @Override
    public Integer updateApi(ApiInputDTO input) {
        LOGGER.info("修改API，入参对象为 {}", JSON.toJSONString(input));
        try {
            if (input == null) {
                throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, "修改API，入参对象为空");
            }

            Api api = BeanUtils.beanCopy(input, Api.class);
            return atomApiService.updateNotNull(api);
        } catch (Exception e) {
            LOGGER.error("修改API，保存失败，{}", e);
            if (e instanceof ApiException) {
                throw (ApiException) e;
            }
            throw new ApiException(ErrorCode.ERR_DATA_OPER_ERROR);
        }
    }

    @Override
    public Integer deleteApi(BaseIdInputDTO input) {
        LOGGER.info("删除API，入参对象为 {}", JSON.toJSONString(input));
        try {
            if (input == null) {
                throw new ApiException(ErrorCode.ERR_REST_INPUT_VALIDATION_REJECTED, "删除API，入参对象为空");
            }

            return atomApiService.delete(input.getId());
        } catch (Exception e) {
            LOGGER.error("删除API，保存失败，{}", e);
            if (e instanceof ApiException) {
                throw (ApiException) e;
            }
            throw new ApiException(ErrorCode.ERR_DATA_OPER_ERROR);
        }
    }
}